#pragma once
#include "PopupWnd.h"
#include "Common.h"
#include "SkinnedEdit.h"
#include "SkinnedButton.h"
#include "ListItem.h"

class CTextInputDlg : public CModalPopupWnd
{
public:
  CTextInputDlg() : CModalPopupWnd()
  {}

	BEGIN_MSG_MAP(CTextInputDlg)
    MESSAGE_HANDLER(WM_CREATE, OnCreate)
    MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
    MESSAGE_HANDLER(WM_SIZE, OnSize)

    MESSAGE_HANDLER(WM_ACTIVATE, OnActivate)
    MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)

    MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorEdit)
    MESSAGE_HANDLER(WM_CTLCOLOREDIT, OnColorEdit)

    MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
    MESSAGE_HANDLER(WM_KEYUP, OnKeyUp)

    COMMAND_ID_HANDLER_EX(IDOK, OnOk)

    CHAIN_MSG_MAP(CModalPopupWnd)
  END_MSG_MAP()

  LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
  {
    LPCREATESTRUCT pCreateStruct = (LPCREATESTRUCT)lParam;

    ::ZeroMemory(&m_sai, sizeof(m_sai));
    m_sai.cbSize = sizeof(m_sai);

    m_btnCancel.SetImages(CTheme::GetImage(timButtonBg), CTheme::GetImage(timButtonCancel), CTheme::GetImage(timButtonDCancel));
    m_btnCancel.Create(m_hWnd, NULL, NULL, WS_CHILD | WS_VISIBLE, 0, IDCANCEL);

    m_editBox.Create(m_hWnd);

    m_btnOk.SetImages(CTheme::GetImage(timButtonBg), CTheme::GetImage(timButtonOk), CTheme::GetImage(timButtonDOk));
    m_btnOk.Create(m_hWnd, NULL, NULL, WS_CHILD | WS_VISIBLE, 0, IDOK);

    HWND hMenuBar = (HWND)::SendMessage(::GetParent(m_hWnd), WM_GETMENUBAR, 0, 0);
    if (hMenuBar)
      ::ShowWindow(hMenuBar, SW_SHOW);

	  ::SipShowIM(SIPF_ON);

    UpdateWindowPosition(false);

    m_editBox.SetFocus();

    SetText(m_text);

    return bHandled = FALSE;
  }

  LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  {
    HWND hMenuBar = (HWND)::SendMessage(::GetParent(m_hWnd), WM_GETMENUBAR, 0, 0);
    if (hMenuBar)
      ::ShowWindow(hMenuBar, SW_HIDE);

    ::SipShowIM(SIPF_OFF);

    return bHandled = FALSE;
  }

  LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  {
    if (wParam != SIZE_MINIMIZED)
    {
      CRect rcClient(0, 0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
      CRect rc = rcClient;

      rc.right = rc.left + rc.Height();
      m_btnCancel.MoveWindow(&rc);

      rc.left = rc.right + 5;
      rc.right = rcClient.right - rc.Height() - 5;
      m_editBox.MoveWindow(&rc);

      rc.left = rc.right + 5;
      rc.right = rcClient.right;
      m_btnOk.MoveWindow(&rc);
      return bHandled = TRUE;
    }
    return bHandled = FALSE;
  }

  LRESULT OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  {
    ::SHHandleWMActivate(m_hWnd, wParam, lParam, &m_sai, 0);
    return 0;
  }

  LRESULT OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  {
    //::SHHandleWMSettingChange(m_hWnd, wParam, lParam, &m_sai);
    ::SendMessage(::GetParent(m_hWnd), uMsg, wParam, lParam);
    UpdateWindowPosition();
    return 0;
  }

  LRESULT OnColorEdit(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  {
    if ((HWND)lParam == m_editBox.m_hWnd)
      return m_editBox.SendMessage(uMsg, wParam, lParam);
    return bHandled = FALSE;
  }

  LRESULT OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  {
    return bHandled = FALSE;
  }

  LRESULT OnKeyUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  {
    switch(wParam)
    {
    case VK_TACTION:
      m_editBox.GetWindowText(m_text);
      EndDialog(IDOK);
      return bHandled = TRUE;
    }

    return bHandled = FALSE;
  }

  void OnOk(UINT uNotifyCode, int nID, CWindow wndCtl)
  {
    m_editBox.GetWindowText(m_text);
    EndDialog(IDOK);
  }

  virtual void UpdateWindowPosition(bool redraw = true)
  {
    CRect rcClient;
    GetClientRect(&rcClient);
    CRect rcw;
    SystemParametersInfo(SPI_GETWORKAREA, 0, &rcw, FALSE);
    HWND hMenuBar = (HWND)::SendMessage(::GetParent(m_hWnd), WM_GETMENUBAR, 0, 0);
    if (hMenuBar)
    {
      RECT rc;
      ::GetWindowRect(hMenuBar, &rc);
      rcw.bottom = min(rcw.bottom, rc.top);
    }
    SIPINFO sipi = {0};
    sipi.cbSize = sizeof(sipi);
    if (::SipGetInfo(&sipi))
    {
      rcw.bottom = min(rcw.bottom, sipi.rcVisibleDesktop.bottom);
    }
    MoveWindow(0, rcw.bottom - rcClient.Height(), rcClient.Width(), rcClient.Height(), redraw);
  }

  const CString& GetText() const
  { return m_text; }
  void SetText(const CString& s)
  { m_text = s; if (m_editBox.m_hWnd) { m_editBox.SetWindowText(s); m_editBox.SetSel(s.GetLength(), -1); } }

  void SetStartKey(int vKey)
  {
    if (vKey)
    {
      keybd_event(vKey, 0, KEYEVENTF_SILENT, 0);
      keybd_event(vKey, 0, KEYEVENTF_KEYUP | KEYEVENTF_SILENT, 0);
    }
  }

protected:
  CString        m_text;

  SHACTIVATEINFO m_sai;

  CSkinnedEdit   m_editBox;
  CSkinnedButton m_btnOk;
  CSkinnedButton m_btnCancel;
};

class CListTextInputDlg : public CTextInputDlg
{
public:
  CListTextInputDlg(CListItem* pItem, const CRect& rcInner) : m_listItem(pItem), m_rcInner(rcInner)
  {}

  virtual void UpdateWindowPosition(bool redraw = true)
  {
    if (m_listItem)
    {
      CRect rc;
      rc = m_listItem->GetRect();
      rc.right = rc.left + m_rcInner.right;
      rc.left += m_rcInner.left;
      rc.bottom = rc.top + m_rcInner.bottom;
      rc.top += m_rcInner.top;
      MoveWindow(&rc, redraw);
    }
    else
    {
      CTextInputDlg::UpdateWindowPosition(redraw);
    }
  }

protected:
  CListItem* m_listItem;
  CRect m_rcInner;
};